#include "bsp_rtc.h"
#include "stm32f4xx_hal.h"
#include "device.h"
#include "rtthread.h"
#include "drv_common.h"
/* USER CODE BEGIN 0 */
#define device  struct rt_device
/* USER CODE END 0 */

RTC_HandleTypeDef hrtc;

/* RTC init function */
rt_err_t MX_RTC_Init(device *dev)
{
	RTC_TimeTypeDef sTime = {0};
	RTC_DateTypeDef sDate = {0};
	RTC_AlarmTypeDef sAlarm = {0};
	/** Initialize RTC Only
	*/
	hrtc.Instance = RTC;
	hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
	hrtc.Init.AsynchPrediv = 127;
	hrtc.Init.SynchPrediv = 255;
	hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
	hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
	hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
	if (HAL_RTC_Init(&hrtc) != HAL_OK)
	{
		Error_Handler();
	}

	/** Initialize RTC and set the Time and Date
	*/
	sTime.Hours = 12;
	sTime.Minutes = 1;
	sTime.Seconds = 0;
	sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sTime.StoreOperation = RTC_STOREOPERATION_RESET;
	if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
	{
		Error_Handler();
	}
	sDate.WeekDay = RTC_WEEKDAY_THURSDAY;
	sDate.Month = RTC_MONTH_NOVEMBER;
	sDate.Date = 10;
	sDate.Year = 20;

	if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
	{
		Error_Handler();
	}
	/** Enable the Alarm A
	*/
	sAlarm.AlarmTime.Hours = 12;
	sAlarm.AlarmTime.Minutes = 5;
	sAlarm.AlarmTime.Seconds = 0;
	sAlarm.AlarmTime.SubSeconds = 0;
	sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
	sAlarm.AlarmMask = RTC_ALARMMASK_HOURS|RTC_ALARMMASK_MINUTES
							  |RTC_ALARMMASK_SECONDS;
	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
	sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	sAlarm.AlarmDateWeekDay = 1;
	sAlarm.Alarm = RTC_ALARM_A;
	if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
	{
		Error_Handler();
	}
	/** Enable Calibrartion
	*/
	if (HAL_RTCEx_SetCalibrationOutPut(&hrtc, RTC_CALIBOUTPUT_1HZ) != HAL_OK)
	{
		Error_Handler();
	}
	return RT_EOK;
}

void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{

  if(rtcHandle->Instance==RTC)
  {
    __HAL_RCC_RTC_ENABLE();
    HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
  }
}

void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
{
  if(rtcHandle->Instance==RTC)
  {
    __HAL_RCC_RTC_DISABLE();

    HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn);
  }
}
rt_err_t MX_RTC_DeInit(device *dev)
{
	HAL_RTC_MspDeInit(&hrtc);
	return RT_EOK;
}

void RTC_Alarm_IRQHandler(void)
{
	rt_interrupt_enter();
	HAL_RTC_AlarmIRQHandler(&hrtc);
	rt_interrupt_leave();
}
/* USER CODE BEGIN 1 */
void Set_time(RTC_time *time)
{
	RTC_TimeTypeDef sTime = {0};
	RTC_DateTypeDef sDate = {0};
	HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
	HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
	sDate.Year = time->year;
	sDate.Month=time->month;
	sDate.Date = time->date;

	sTime.Hours = time->hour;
	sTime.Minutes =time->minute;
	sTime.Seconds = time->seconds;

	if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
	{
		while(1);
	}
	if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
	{
		while(1);
	}
}
void Get_time(RTC_time *time)
{
	RTC_TimeTypeDef sTime = {0};
	RTC_DateTypeDef sDate = {0};
	HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
	time->year=sDate.Year;
	time->month=sDate.Month;
	time->date=sDate.Date;

	time->hour=sTime.Hours ;
	time->minute=sTime.Minutes ;
	time->seconds=sTime.Seconds;
}
void Set_Alarm(RTC_time *time)
{
	RTC_AlarmTypeDef sAlarm = {0};
	sAlarm.AlarmTime.Hours = time->hour;
	sAlarm.AlarmTime.Minutes = time->minute;
	sAlarm.AlarmTime.Seconds = time->seconds;
	sAlarm.AlarmTime.SubSeconds = 0;
	sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
	sAlarm.AlarmMask = RTC_ALARMMASK_HOURS|RTC_ALARMMASK_MINUTES
							  |RTC_ALARMMASK_SECONDS;
	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
	sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	sAlarm.AlarmDateWeekDay = 1;
	sAlarm.Alarm = RTC_ALARM_A;
	if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
	{
	Error_Handler();
	}
}
void Get_Alarm(RTC_time *time)
{
	RTC_AlarmTypeDef sAlarm = {0};
	HAL_RTC_GetAlarm(&hrtc,&sAlarm,RTC_ALARM_A,RTC_FORMAT_BIN);
	time->hour=sAlarm.AlarmTime.Hours ;
	time->minute=sAlarm.AlarmTime.Minutes ;
	time->seconds=sAlarm.AlarmTime.Seconds;
}
device Rtc_dev={0};
int Register_Rtc_dev()
{
	Rtc_dev.init=MX_RTC_Init;
	Rtc_dev.close=MX_RTC_DeInit;
	return rt_device_register(&Rtc_dev,"RTC",RT_DEVICE_FLAG_RDWR);   
}

DEVICE_INIT(Register_Rtc_dev);
/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/






